/*
 * @描述: 上传下载页面逻辑
 * @版权所有: 广东国星科技有限公司
 * @商业授权: www.mscodecloud.com
 */
import React, { PureComponent, Fragment } from 'react';
import { formatMessage } from 'umi-plugin-react/locale';
import { connect } from 'dva';
import moment from 'moment';
import numeral from 'numeral';
import { Row, Col, Card, Form, Input, Icon, Button, Modal, message, Divider, Popconfirm, Upload } from 'antd';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { saveAs } from 'file-saver';
import ProTable from '@ant-design/pro-table';

import styles from './File.less';

const FormItem = Form.Item;
const getValue = obj => Object.keys(obj).map(key => obj[key]).join(',');

function handleChange() { }; // NOSONAR

function beforeUpload(file) {
  const isst10M = file.size / 1024 / 1024 < 10;
  if (!isst10M) {
    message.error(formatMessage({ id: 'app.file.isst10m' }));
  }
  const isNotEmpty = file.size > 0;
  if (!isNotEmpty) {
    message.error(formatMessage({ id: 'app.file.isnotempty' }));
  }
  return isst10M && isNotEmpty;
}

let uploadLoading = false;

const props = {
  name: 'file',
  listType: "picture-card",
  className: "avatar-uploader",
  showUploadList: false,
  beforeUpload: beforeUpload,
  action: '/api/file/file/uploadFile',
  headers: {
    Authorization: 'Bearer ' + localStorage.getItem('mscode_token'),
    RoleCode: localStorage.getItem('mscode_authority'),
  },
  onChange(info) {
    if (info.file.status === 'uploading') {
      uploadLoading = true;
      return;
    }
    if (info.file.status === 'done') {
      message.success(formatMessage({ id: 'app.file.upload-success' }));
      handleChange();
    } else if (info.file.status === 'error') {
      message.error(`${info.file.name} file upload failed.`);
    }
    uploadLoading = false;
  }
};

const UploadForm = Form.create()(
  class extends React.Component {
    render() {
      const { uploadVisible, onCancel, sysUserId } = this.props;
      const uploadButton = (
        <div>
          <Icon type={uploadLoading ? 'loading' : 'plus'} />
          <div className="ant-upload-text">{formatMessage({ id: 'app.common.upload' })}</div>
        </div>
      );
      return (
        <Modal
          destroyOnClose
          centered
          visible={uploadVisible}
          title={formatMessage({ id: 'app.file.upload-file' })}
          okText={formatMessage({ id: 'app.common.confirm' })}
          onCancel={onCancel}
          footer={null}
        >
          <center className={styles['ant-upload-picture-card-wrapper']}>
            <Upload {...props} data={{ id: sysUserId }}>
              {uploadButton}
            </Upload>
          </center>
        </Modal>
      );
    }
  }
);

/* eslint react/no-multi-comp:0 */
@connect(({ file, loading, user }) => ({
  file,
  loading: loading.models.file,
  currentUser: user.currentUser
}))
@Form.create()
class File extends PureComponent {
  state = {
    selectedRows: [],
    formValues: {},
    uploadVisible: false,
    hiddenMenuButton: localStorage.getItem('mscode_menubutton')
  };

  columns = [
    {
      title: formatMessage({ id: 'app.file.original-filename' }),
      copyable: true,
      ellipsis: true,
      dataIndex: 'originalFilename'
    },
    {
      title: formatMessage({ id: 'app.file.file-size' }),
      dataIndex: 'fileSize',
      render: val => <span>{numeral(val).format('0.00')}</span>
    },
    {
      title: formatMessage({ id: 'app.file.content-type' }),
      copyable: true,
      ellipsis: true,
      dataIndex: 'contentType'
    },
    {
      title: formatMessage({ id: 'app.common.create-time' }),
      dataIndex: 'createTime',
      sorter: true,
      render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>
    },
    {
      title: formatMessage({ id: 'app.common.operate' }),
      align: 'center',
      render: (text, record) => (
        <Fragment>
          {this.state.hiddenMenuButton.indexOf('upload-download:download') !== -1 ? null :
            <a onClick={() => this.download(event, record)}><Icon type="download" />{formatMessage({ id: 'app.common.download' })}</a>
          }
          <Divider type="vertical" />
          <Popconfirm title={formatMessage({ id: 'app.common.confirm-delete' })} onConfirm={() => this.deleteItem(record.id)}>
            {this.state.hiddenMenuButton.indexOf('upload-download:delete') !== -1 ? null :
              <a><Icon type="delete" />{formatMessage({ id: 'app.common.delete' })}</a>
            }
          </Popconfirm>
        </Fragment>
      )
    }
  ];

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'file/fetch'
    });
    handleChange = () => {
      dispatch({
        type: 'file/fetch'
      });
    }
  }

  showModal = (values, field) => {
    this.setState({ uploadVisible: true });
  };

  handleCancel = (values, field) => {
    this.setState({ uploadVisible: false });
  };

  saveUploadFormRef = uploadFormRef => {
    this.uploadFormRef = uploadFormRef;
  };

  download = (event, record) => {
    event.preventDefault();
    const { dispatch } = this.props;
    dispatch({
      type: 'file/download',
      payload: {
        originalFilename: record.originalFilename,
        url: record.url
      }
    }).then(response => {
      if (response.size === 0) {
        message.error(formatMessage({ id: 'app.file.cannotfind' }));
      } else {
        saveAs(response, record.originalFilename);
      }
      dispatch({
        type: 'file/fetch'
      });
    });
  };

  handleBasicTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const { formValues } = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = { ...obj };
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      currentPage: pagination.current,
      pageSize: pagination.pageSize,
      ...formValues,
      ...filters
    };
    if (sorter.field) {
      params.sorter = `${sorter.field}_${sorter.order}`;
    }

    dispatch({
      type: 'file/fetch',
      payload: params
    });
  };

  handleFormReset = () => {
    const { form, dispatch } = this.props;
    form.resetFields();
    this.setState({
      formValues: {}
    });
    dispatch({
      type: 'file/fetch',
      payload: {}
    });
  };

  deleteItem = id => {
    const { dispatch } = this.props;
    dispatch({
      type: 'file/delete',
      payload: {
        id: id
      }
    }).then(response => {
      if (response.message == 'success') {
        this.setState({
          selectedRows: []
        });
        message.success(formatMessage({ id: 'app.common.delete-success' }));
      } else {
        message.warning(response.message);
      }
      dispatch({
        type: 'file/fetch',
        payload: {}
      });
    });
  };

  handleDeleteClick = () => {
    const { selectedRows } = this.state;

    if (selectedRows.length === 0) {
      message.warning(formatMessage({ id: 'app.common.choose-delete' }));
      return;
    }

    Modal.confirm({
      title: formatMessage({ id: 'app.common.batch-delete' }),
      content: formatMessage({ id: 'app.common.confirm-batch-delete' }),
      okText: formatMessage({ id: 'app.common.confirm' }),
      cancelText: formatMessage({ id: 'app.common.cancel' }),
      onOk: () => this.deleteItem(selectedRows.map(row => row.id)),
    });
  };

  handleSelectRows = rows => {
    this.setState({
      selectedRows: rows
    });
  };

  handleSearch = e => {
    if (e) {
      e.preventDefault();
    }
    const { dispatch, form } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const values = {
        ...fieldsValue
      };
      this.setState({
        formValues: values
      });
      dispatch({
        type: 'file/fetch',
        payload: values
      });
    });
  };

  renderSimpleForm() {
    const { form: { getFieldDecorator } } = this.props;
    return (
      <Form onSubmit={this.handleSearch} layout="inline">
        <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
          <Col md={8} sm={24}>
            <FormItem label={formatMessage({ id: 'app.file.original-filename' })}>
              {getFieldDecorator('originalFilename')(<Input placeholder={formatMessage({ id: 'app.common.enter' })} />)}
            </FormItem>
          </Col>
          <Col md={8} sm={24}>
            <FormItem label={formatMessage({ id: 'app.file.content' })}>
              {getFieldDecorator('content')(<Input placeholder={formatMessage({ id: 'app.common.enter' })} />)}
            </FormItem>
          </Col>
          <Col md={8} sm={24}>
            <span className={styles.submitButtons}>
              <Button type="primary" htmlType="submit" icon="search">
                {formatMessage({ id: 'app.common.query' })}
              </Button>
              <Button style={{ marginLeft: 8 }} onClick={this.handleFormReset} type="primary" icon="reload">
                {formatMessage({ id: 'app.common.reset' })}
              </Button>
            </span>
          </Col>
        </Row>
      </Form>
    );
  }

  renderForm() {
    return this.renderSimpleForm();
  }

  render() {
    const { file: { data }, loading, currentUser } = this.props;
    // const { selectedRows } = this.state;
    const rowSelection = {
      onChange: (selectedRowKeys, selectedRows) => {
        this.handleSelectRows(selectedRows);
      }
    };
    return (
      <PageHeaderWrapper>
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListForm}>{this.renderForm()}</div>
            <div className={styles.tableListOperator}>
              {this.state.hiddenMenuButton.indexOf('upload-download:upload') !== -1 ? null :
                <Button icon="cloud-upload" type="primary" onClick={(values) => { this.showModal(values, 'upload') }}>
                  {formatMessage({ id: 'app.common.upload' })}
                </Button>
              }
              {this.state.hiddenMenuButton.indexOf('upload-download:delete') !== -1 ? null :
                <Button icon="delete" type="danger" ghost onClick={this.handleDeleteClick}>
                  {formatMessage({ id: 'app.common.batch-delete' })}
                </Button>
              }
            </div>
            <ProTable
              bordered={true}
              search={false}
              rowKey={record => record.id}
              rowSelection={rowSelection}
              loading={loading}
              dataSource={data ? data.list : []}
              pagination={data ? data.pagination : {}}
              columns={this.columns}
              onChange={this.handleBasicTableChange}
              options={{
                density: true,
                reload: () => {
                  this.handleSearch();
                },
                fullScreen: true,
                setting: true,
              }}
            />
          </div>
        </Card>
        <UploadForm
          wrappedComponentRef={this.saveUploadFormRef}
          uploadVisible={this.state.uploadVisible}
          onCancel={(values) => { this.handleCancel(values, 'upload') }}
          sysUserId={currentUser.id} />
      </PageHeaderWrapper>
    );
  }
}

export default File;
